/**
 * store就是保存数据的地方，可以将他看成一个容器，整个应用只能有一个store
 *
 * redux提供createStore这个函数，用来生成store
 *
 * store对象包含所有数据。如果想得到某个时点的数据，
 * 就要对Store生成快照，这种时点的数据集合，叫做state
 * 当前时刻的State,可以通过store.getState()拿到
 *
 * state的变化，会导致view的变化，但是用户接触不到state，
 * 只能接触到view，所以，state的边户必须是view导致的，action
 * 就是view发出的通知，表示state应该要发生变化了。
 *
 * action是一个对象，其中的type属性是必须的，表示action的名称。
 * 其他属性可以任意设置
 *
 * action描述当前发生的事情，改变state的唯一办法，就是使用action，他会运送数据到store
 *
 * store收到action以后，必须给出一个心得state，这样view才会发生变化
 * 这种state的计算过程就叫做Reducer
 *
 * reducer是一个函数，它接受action和当前state作为参数，返回一个新的state
 *
 * 整个应用的初始状态，可以作为state的默认值
 *
 * 实际应用中Reducer函数不用手动调用，store.dispatch
 * 方法会触发reducer的自动执行，因此,store需要知道reducer函数，
 * 做法就是在生成store的时候，将Reducer传入createStore方法
 *
 * createStore接受Reducer作为参数，生成一个新的Store，之后每当store.dispatch发送
 * 过来一个新的Action,就会自动调用Reducer,得到新的State
 *
 * Reducer函数最重要的特征是，它是一个纯函数，只要是同样的输入，必定得到同样的输出
 * 由于Reducer是纯函数，就可以保证同样的State，必定得到同样的View，单也正因为这一点，
 * Reducer函数里面不能改变State，必须返回一个全新的对象
 * 这样的好处是，任何时候，与某个View对应的State总是一个不变的对象
 *
 * Redux提供了一个combineReducers方法，用于Reducer的拆分
 * 只要定义各个子Reducer函数，然后以对象的形式封装到此方法之中，将他们合成一个大的Reducer
 * 这样的写法有一个前提，就是State的属性名必须与子Reducer同名，如果不同名，则要去另取属性名
 * 总之，combineReducers()做的就是产生一个整体的Reducer函数，该函数根据
 * State的key去执行相应的子Reducer，并将返回结果合并成一个大的State对象。
 *
 */
